/**
 * @Unit    : 
 * @Version : 1.0
 * @Author  : 靳普诏
 * @Brief   : 简单介绍
 */

#ifndef _ABC_RING_BUFF_H_
#define _ABC_RING_BUFF_H_

#include "abc_types.h"

#ifdef __cplusplus
extern "C"
{
#endif

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/* Abc_TRingBuff - 环形缓冲区类 */

// 注:
// 1. 为了效率不检查 Abc_TRingBuff* self 是否合法, 此参数需要外部来维护.
// 2. 为了多线程存取安全, Push 和 Pop 分属二个线程时可以同时操作而不需要加锁,
//    但多线程 Push 时必须用锁控制, 多线程 Pop/Peek 时必须用锁控制!

// ---------------- 类型定义 ----------------

// 定义 Abc_TRingBuff 对象数据
typedef struct Abc_TRingBuffTag Abc_TRingBuff;
struct Abc_TRingBuffTag
{
   // ------ 公开数据成员 ------
   // ??? ... ...
   /*
   void*          Tag;                 // 自定义数据
   */

   // ------ 私有数据成员 ------
   // ??? ... ...
   void*          Data[8];             // 注: 对象占用数据不能修改
   // char           ExtData[sizeof(Txx1) + sizeof(Txx2)];
} ;

// Abc_TRingBuff 类数据尺寸
#define Abc_TRingBuffSizeOf  sizeof(Abc_TRingBuff)

// 定义 Abc_TRingBuff 对象类型
typedef Abc_TRingBuff*    ABC_PRingBuff;

// ---------------- 构造函数和析构函数 ----------------

// 初始化/释放 Abc_TRingBuff 对象数据
// 1. Abc_TRingBuffInit 返回的对象就是 data 指针, 且对象必须使用 Abc_TRingBuffFini 来
//    释放数据;
// 2. 本组函数适用于不分配对象指针情况, 如不分配对象指针的函数局部变量或结构中.
// 参数:
//    buffer      缓冲区
//    buff_size   缓冲区尺寸, buff_size >= 16
Abc_TRingBuff* Abc_TRingBuffInit(Abc_TRingBuff* self, Byte* buffer, DWord buff_size);
void Abc_TRingBuffDone(Abc_TRingBuff* self);

// Abc_TRingBuff* Abc_TRingBuffCreate(Byte* buffer, DWord buff_size);
// void Abc_TRingBuffFree(Abc_TRingBuff* self);

// ---------------- 属性方法 ----------------
Int32    Abc_TRingBuffSize(Abc_TRingBuff* self);
Int32    Abc_TRingBuffMaxSize(Abc_TRingBuff* self);
Int32    Abc_TRingBuffPushSize(Abc_TRingBuff* self);
Int32    Abc_TRingBuffPopSize(Abc_TRingBuff* self);
Bool     Abc_TRingBuffIsEmpty(Abc_TRingBuff* self);

// ---------------- 公有方法 ----------------

// 数据压入/预读取/弹出缓冲区, 注: 若 data 为 NULL 则返回值为 -1
Int32    Abc_TRingBuffPush(Abc_TRingBuff* self, const Byte* data, Int32 size);
Int32    Abc_TRingBuffPeek(Abc_TRingBuff* self, Byte* data, Int32 size);
Int32    Abc_TRingBuffPop(Abc_TRingBuff* self, Byte* data, Int32 size);

Int32    Abc_TRingBuffLose(Abc_TRingBuff* self, Int32 size);
Int32    Abc_TRingBuffClear(Abc_TRingBuff* self);

#ifdef __cplusplus
}  // extern "C"
#endif

#endif

